﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using SPUtils;
using StackExchange.Redis;
using System.Text.Json;

namespace RedisUtils
{
    public partial class Redis
    {
        public string Conn_To_DB(out SqlSugar.ISqlSugarClient cn)
        {
            string sErr = "";

            string sDBName;
            cn = null;

            try
            {
                // Due to the lack of base comp table, I re-write this by using db-lookup
                sDBName = DBUtils.SPRPropDatabaseName;

                sErr = DBUtils.ConnectToDB_ROMMS(sDBName, out cn);
                if (sErr != "") goto Get_Out;

                Console.WriteLine(" DB:\tConnected to DB.\n");
            }

            catch (Exception ex)
            {
                sErr = ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;
        }

        private string SaveRedis_AliasID(Dictionary<string, int> dicToRedis, IDatabase xRedisDB)
        {
            string sErr = "";

            string hashKey = "AliasID";

            try
            {
                if (xRedisDB.KeyExists(hashKey))
                {
                    Console.WriteLine($" Redis:\t[Warning]\tAlias-ID list already exists.\n");
                    //goto Get_Out;
                }

                foreach (KeyValuePair<string, int> kvp in dicToRedis)
                {
                    xRedisDB.HashSet(hashKey, new HashEntry[]
                    {
                        new(kvp.Key, kvp.Value),
                    });
                }

                Console.WriteLine($" Redis:\tAlias-ID list ({dicToRedis.Count()} data) has been saved into Redis.\n");
            }
            catch (Exception ex)
            {
                sErr = ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;

        }

        private string SaveRedis_Props(Dictionary<int, string> dicToRedis, PropCat xType, string sPropType, IDatabase xRedisDB)
        {
            string sErr = "";
            string hashKey;

            try
            {
                if (xType == PropCat.PureConstProp) 
                {
                    hashKey = xType.ToString(); 
                }
                else
                {
                    hashKey = sPropType;
                }

                if (xRedisDB.KeyExists(hashKey))
                {
                    Console.WriteLine($" Redis:\t[Warning]\t{hashKey} already exists.\n");
                    //goto Get_Out;
                }

                foreach (KeyValuePair<int, string> kvp in dicToRedis)
                {
                    xRedisDB.HashSet(hashKey, new HashEntry[]
                    {
                        new(kvp.Key, kvp.Value),
                    });
                }

                Console.WriteLine($" Redis:\t{hashKey} ({dicToRedis.Count()} data) has been saved into Redis.\n");
            }
            catch (Exception ex)
            {
                sErr = ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;

        }

        private string SaveRedis_Props(Dictionary<string, string> dicToRedis, PropCat xType, string sPropType, IDatabase xRedisDB)
        {
            string sErr = "";
            string hashKey;

            try
            {
                if (xType == PropCat.PureConstProp)
                {
                    hashKey = xType.ToString();
                }
                else
                {
                    hashKey = sPropType;
                }

                if (xRedisDB.KeyExists(hashKey))
                {
                    Console.WriteLine($" Redis:\t[Warning]\t{hashKey} already exists. Skip writing.\n");
                    //goto Get_Out;
                }

                foreach (KeyValuePair<string, string> kvp in dicToRedis)
                {
                    xRedisDB.HashSet(hashKey, new HashEntry[]
                    {
                        new(kvp.Key, kvp.Value),
                    });
                }

                Console.WriteLine($" Redis:\t{hashKey} ({dicToRedis.Count()} data) has been saved into Redis.\n");
            }
            catch (Exception ex)
            {
                sErr = ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;

        }

        private string Assemble_Prop_Str(List<string[]> lstDSContent, List<int> lstCompID, PropCat xType, ref Dictionary<int, string> dicToRedis)
        {
            string sErr = "";

            int iCompID;
            string[] arrContent;
            string sStr;
            List<string> lstProp = new List<string>();
            Dictionary<string, string> dicProps;

            try
            {

                var options = new JsonSerializerOptions
                {
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                };


                for (int i = 0; i < lstCompID.Count; i++)
                {
                    iCompID = lstCompID[i];
                    arrContent = lstDSContent[i];

                    if (xType == PropCat.PureConstProp)
                    {
                        lstProp = m_lstPureCompProp.Select(e => e.ToString()).ToList();
                    }
                    else
                    {
                        lstProp = Enumerable.Range(1, 20)
                                 .Select(i => i.ToString())
                                 .ToList();
                    }

                    if (bUseJson == true)
                    {
                        dicProps = arrContent.Skip(1)
                                   .Select((value, index) => new { Key = lstProp[index], Value = value })
                                   .ToDictionary(pair => pair.Key, pair => pair.Value);

                        sStr = JsonSerializer.Serialize(dicProps, options);
                    }
                    else
                    {
                        sStr = string.Join(",", arrContent);
                    }

                    dicToRedis[iCompID] = sStr;
                }
            }

            catch (Exception ex)
            {
                sErr = "Type = " + xType.ToString() + "\n";
                sErr += ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;
        }

        private string Assemble_Prop_Str(List<string[]> lstDSContent, List<string> lstCompID, PropCat xType, ref Dictionary<string, string> dicToRedis)
        {   // reload for binary
            string sErr = "";

            string sCompIDPair;
            string[] arrContent;
            string sStr;
            List<string> lstProp = new List<string>();
            Dictionary<string, string> dicProps;

            try
            {
                var options = new JsonSerializerOptions
                {
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                };


                for (int i = 0; i < lstCompID.Count; i++)
                {
                    sCompIDPair = lstCompID[i];
                    arrContent = lstDSContent[i];

                    lstProp = Enumerable.Range(1, 20)
                        .Select(i => i.ToString())
                        .ToList();


                    if (bUseJson == true)
                    {
                        dicProps = arrContent.Skip(1)
                                   .Select((value, index) => new { Key = lstProp[index], Value = value })
                                   .ToDictionary(pair => pair.Key, pair => pair.Value);

                        sStr = JsonSerializer.Serialize(dicProps, options);
                    }
                    else
                    {
                        sStr = string.Join(",", arrContent);
                    }
                    
                    dicToRedis[sCompIDPair] = sStr;
                }
            }

            catch (Exception ex)
            {
                sErr = "Type = " + xType.ToString() + "\n";
                sErr += ex.Message + "\r\n" + ex.StackTrace;
                goto Get_Out;
            }

        Get_Out:

            if (sErr != "")
            {
                sErr += "\r\nClass: " + MethodBase.GetCurrentMethod()?.DeclaringType + "  Method: " + MethodBase.GetCurrentMethod()?.Name;
            }
            return sErr;
        }

    }
}
